package com.reggie.module.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.common.ResultResponseVo;
import com.reggie.common.enums.PublicEnums;
import com.reggie.common.enums.backend.DishEnum;
import com.reggie.module.entity.dto.dishDto.DishDto;
import com.reggie.module.entity.po.Dish;
import com.reggie.module.entity.po.DishFlavor;
import com.reggie.module.entity.vo.dishVo.DishVo;
import com.reggie.module.mapper.CategoryMapper;
import com.reggie.module.mapper.DishFlavorMapper;
import com.reggie.module.mapper.DishMapper;
import com.reggie.module.mapper.DishStatusDtoMapper;
import com.reggie.module.service.DishFlavorService;
import com.reggie.module.service.DishService;
import com.reggie.utils.FileUpdateUtil;
import com.reggie.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.reggie.common.Constant.DISH_CACHE;

/**
 * @Author 早睡蛋
 * @Date 2022/9/17 14:29:22
 * @Desc:
 */
@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private DishStatusDtoMapper dishStatusDtoMapper;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 图片上传
     *
     * @param file
     * @param imagesUrl
     * @param dataUrl
     * @return
     */
    @Override
    public ResultResponseVo upload(MultipartFile file, String imagesUrl, String dataUrl) {
        FileUpdateUtil fileUpdateUtil = new FileUpdateUtil();
        Map<String, String> map = fileUpdateUtil.uploadImages(file, imagesUrl, dataUrl);
        return PublicEnums.SUCCESS.getResultResponseVo().setData(map);
    }

    /**
     * 添加菜品
     *
     * @param dishDto
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResultResponseVo saveDish(DishDto dishDto, HttpServletRequest request) {
        Dish dish = dishDto.changeToDish(request);
        int insertDish = dishMapper.insert(dish);
        if (dishDto.getFlavors().size() > 0) {
            dishDto.changeDishFlavor(dish.getId(), request);
            List<DishFlavor> flavors = dishDto.getFlavors();
            flavors.stream().collect(Collectors.toList());
            dishFlavorService.saveBatch(flavors);
        }
        if (insertDish > 0) {
            return DishEnum.ADD_OK.getResultResponseVo();
        }
        return DishEnum.ADD_FAIL.getResultResponseVo();
    }

    /**
     * 菜品分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public ResultResponseVo selectByPage(int page, int pageSize, String name) {
        Page<Dish> dishPage = new Page<>(page, pageSize, true);
        QueryWrapper<Dish> dishQueryWrapper = new QueryWrapper<>();
        dishQueryWrapper.select("id", "name", "category_id", "image", "status", "price", "update_time")
                .last("order by update_time desc");
        if (StringUtils.isNotEmpty(name)) {
            dishQueryWrapper.like("name", name);
        }
        IPage<Dish> dishIPage = dishMapper.selectPage(dishPage, dishQueryWrapper);
        List<Dish> dishList = changeToDishListVo(dishIPage.getRecords());
        dishIPage.setRecords(dishList);
        return DishEnum.SUCCESS.getResult().setData(dishIPage);

    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @Override
    public ResultResponseVo getDishById(Long id, HttpServletRequest request) {
        Dish dish = dishMapper.selectById(id);
        DishVo dishVo = dish.changeToDishVo(dish, request);
        Long dishId = dish.getId();
        List<DishFlavor> dishFlavorList = dishFlavorMapper.selectByDishId(dishId);
        dishVo.setFlavors(dishFlavorList);
        return DishEnum.SUCCESS.getResultResponseVo().setData(dishVo);
    }

    /**
     * 修改菜品
     *
     * @param dishDto
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResultResponseVo updateDish(DishDto dishDto, HttpServletRequest request) {
        Long id = dishDto.getId();
        Integer deleteByDishId = dishFlavorMapper.deleteByDishId(id);
        if (deleteByDishId <= 0) {
            return DishEnum.UPDATE_FAIL.getResultResponseVo();
        }
        Dish dish = dishDto.updateDish(request);
        dishDto.changeDishFlavor(dish.getId(), request);
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors.stream().collect(Collectors.toList());

        Integer updateDish = dishMapper.updateDish(dish);
        boolean saveBatch = dishFlavorService.saveBatch(flavors);
        if (updateDish > 0 && saveBatch) {
            return DishEnum.UPDATE_OK.getResultResponseVo();
        }
        return DishEnum.UPDATE_FAIL.getResultResponseVo();
    }

    /**
     * 删除菜品
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public ResultResponseVo deleteDish(List<Long> ids) {
        int flag = countStatusBeforeDelete(ids);
        if (flag == 1) {
            return DishEnum.STATUS_ON.getResultResponseVo();
        }
        int deleteBatchIds = dishMapper.deleteBatchIds(ids);
        if (deleteBatchIds > 0) {
            return DishEnum.DEL_OK.getResultResponseVo();
        }
        return DishEnum.DEL_FAIL.getResultResponseVo();
    }

    /**
     * 根据菜品分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    public ResultResponseVo getListById(Long categoryId, Integer status) {
        List<DishVo> dishVoList = null;
        String key = DISH_CACHE + categoryId + "_" + status;
        dishVoList = (List<DishVo>) redisTemplate.opsForValue().get(key);
        if (dishVoList != null) {
            return DishEnum.SUCCESS.getResultResponseVo().setData(dishVoList);
        }
        QueryWrapper<Dish> dishQueryWrapper = new QueryWrapper<>();
        dishQueryWrapper.select("id", "name", "image", "price")
                .eq("category_id", categoryId);
        if (status == null) {
            dishQueryWrapper.eq("status", 1);
        } else {
            dishQueryWrapper.eq("status", status);
        }
        List<Dish> dishList = dishMapper.selectList(dishQueryWrapper);
        dishVoList = changeToDishVoList(dishList);
        redisTemplate.opsForValue().set(key,dishVoList,60, TimeUnit.SECONDS);
        return DishEnum.SUCCESS.getResultResponseVo().setData(dishVoList);
    }

    /**
     * 通过category_id查询对应的分类名称
     *
     * @param dishes
     * @return
     */
    public List<Dish> changeToDishListVo(List<Dish> dishes) {
        List<Dish> dishList = new ArrayList<>();
        for (Dish dish : dishes) {
            String categoryName = categoryMapper.selectNameById(dish.getCategoryId());
            dish.setCategoryName(categoryName);
            dishList.add(dish);
        }
        return dishList;
    }


    public int countStatusBeforeDelete(List<Long> ids) {
        List<Dish> dishList = new ArrayList<>();
        for (Long id : ids) {
            QueryWrapper<Dish> dishQueryWrapper = new QueryWrapper<>();
            dishQueryWrapper.select("status")
                    .eq("status", 1)
                    .eq("id", id);
            Dish dish = dishMapper.selectOne(dishQueryWrapper);
            if (dish != null) {
                dishList.add(dish);
            }
        }
        if (dishList.size() > 0) {
            return 1;
        }
        return 0;
    }

    public List<DishVo> changeToDishVoList(List<Dish> dishList) {
        List<DishVo> dishVoList = new ArrayList<>();
        for (Dish dish : dishList) {
            DishVo dishVo = new DishVo();
            dishVo.setId(dish.getId());
            dishVo.setImage(dish.getImage());
            dishVo.setName(dish.getName());
            dishVo.setPrice(dish.getPrice());
            List<DishFlavor> dishFlavorList = dishFlavorMapper.selectByDishId(dish.getId());
            dishVo.setFlavors(dishFlavorList);
            dishVoList.add(dishVo);
        }
        return dishVoList;
    }


}
